/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simulateurs.model.scheduler;

import java.util.ArrayList;
import simulateurs.model.Model;
import simulateurs.model.monde.Robot;
import simulateurs.model.monde.StringPoint;


/**
 *
 * @author Lunesco
 */
public class Scheduler {
    private Model model=null;
    private Horloge horloge=null;
    private boolean arret=true;

    public Scheduler(Model model){
        this.model=model;
        horloge=new Horloge(50);
    }
    
    
    // devra piocher dans une liste d'evenement, update ne devrait pas avoir de parametre !!
    // public void update(){
    public void update(){
        this.horloge.setStartTime();
        
        if(!this.arret) {
            StringPoint action;
			
            // if(even == Evenement.RIEN)
            //   System.out.println("**** Levenement est RIEN");
            //System.out.println("Dans la fonction update du scheduler");
            for(int j=0;j<this.getModel().getArene().getListeEquipes().size();j++){
                // pour chaque equipe
                //System.out.println("Dans la 1ere boucle for a l'indice : " + j);
                
                //System.out.println("--- la taille de la liste de robots est : " + this.getModel().getArene().getListeEquipes().get(0).getListeRobots().size());
                for(int i=0;i<this.getModel().getArene().getListeEquipes().get(j).getListeRobots().size();i++){
                    // pour chaque robot de l'equipe courante
                    // System.out.println("Dans la 2eme boucle for a l'indice : " + i);
                   
                    
                    ArrayList<StringPoint> events;
                    Robot o=this.getModel().getArene().getListeEquipes().get(j).getListeRobots().get(i);
                    
                    // 1)devrait appeler une fonction scan dans robot, qui renvoie une liste de couples (evenement,point)
                    // c'est a dire les objets dans un rayon de 3 metres
                    // 2)devrait appeler une fonction qui prend la liste precedente et renvoie l'evenement le plus proche et important
                    // 3) appel update de l'AUTOMATE avec comme parametre l'evenement
                    // o.update(Event);
                    
                    // a ce stade je possederai une liste d'evenements / conditions
                    
                    // appel betement chaque automate du robot avec l'evenement attention!!!
                    //System.out.println("Avant la 3eme boucle for automate ");
                    // RECTIFIé pb liste d'automate vide ??? liste d'automate mande NEW ArrayList<Automate>
                    /*
                     * if (o.getAutomates() == null)
                     * {
                     * System.out.println("La liste n'est pas initialisee");
                     * }
                     */
                    
                    
                    
                    for(int k=0; k < o.getAutomates().size();k++){
                        
                        //System.out.println("Equipe : " + j + " et Robot numero : " + i + " et automate : " + k);
                        
                        //System.out.println("la taille de la liste d'automates est : " + o.getAutomates().size());
                        // System.out.println("Dans la 3eme boucle for automate a l'indice : " + k);
                        //fonction de detection timer, renvoie une liste d'"events"
                        events = o.checkTimer();
                        //fonction de detection emotion, renvoie une liste d'"events"
                        
                        //fonction de détection de mur, renvoie une liste d'"events"
                        events.addAll(o.checkMur(getModel().getArene().getLargeur(),getModel().getArene().getHauteur()));
                        // System.out.println("fin de check mur x2");
                        
                        //fonction de détection "j'ai la balle", renvoie une liste d'"events"
                        events.addAll(o.checkIHaveABall());
                        
                        //fonction de détection REAVECBALLE, renvoie une liste d'"events", checkReAvecBalle
                        
                       
                        
                        //System.out.println("Avant fonction scan a l'indice : " + k);
                        // appel de la fonction scan
                        events.addAll(o.scan(model.getArene().getListeEquipes(), model.getArene().getListeBalles()));
                        // System.out.println("Apres fonction scan a l'indice : " + k);
                        
              /*          System.out.println("## Affichage de la liste des events apres tous les checks");
            for(int h = 0; h < events.size();h++){
                System.out.println("event num : " + h + ", nom : " + events.get(h).getEventAction() + " au point : (" + events.get(h).getPosition().getAbscisse() + "," + events.get(h).getPosition().getOrdonnee() + ")");
            }
              */          
                        // /!\ il faut trier la liste des event par distance croissante !
                        StringPoint.tri_bulles(events, o.getCentre());
                        
                        //System.out.println("Avant fonction update de l'automate a l'indice : " + k);
                        
                        
                        // probleme dans la fonction update de l'automate
                        
            
                        action = o.getAutomates().get(k).update(events); // recupere une action a executer !!
                        //System.out.println("Apres fonction update de l'automate a l'indice : " + k);
                        
                        //System.out.println("la taille de la liste d'automates est : " + o.getAutomates().size());
                        //System.out.println("Avant update de robot, taille liste events : " + events.size());
                        if(action!= null){ // les strings sont differents
                            //System.out.println("Avant appel de la fonction action : " + k);
                            
                            o.update(action,model.getArene().getListeEquipes(),model.getArene().getListeBalles(),model.getArene().getListeButs()); // execute l'action renvoyée par l'automate si match
                            // System.out.println("Apres appel de la fonction action : " + k);
                        }
                        else{
                            //System.out.println("Aucune action n'a été générée par l'automate PB : ");
                        }
                        
                        //System.out.println("Dans la 3eme boucle for automate a l'indice : " + k);
                       // System.out.println("La direction est : " + o.getDirection());
                        //System.out.println("");
                        
                         //System.out.println("----- La position du robot est  : (" + o.getCentre().getAbscisse() + "," + o.getCentre().getOrdonnee() + ")");
                         //System.out.println("----- La position du but est  : (" + o.getBut().getCentre().getAbscisse() + "," + o.getBut().getCentre().getOrdonnee() + ")");
                    
                         //System.out.println("----- La position de la balle est  : (" + model.getArene().getListeBalles().get(0).getCentre().getAbscisse() + "," + model.getArene().getListeBalles().get(0).getCentre().getOrdonnee() + ")");
                    
                        
                    }
                    
                   
                    //System.out.println("Dans la 2eme boucle for a l'indice : " + i);
                    //System.out.println("a taille de la liste des robots est " + this.getModel().getArene().getListeEquipes().get(i).getListeRobots().size());
                    //System.out.println("La taille de la liste des equipes est : " +this.getModel().getArene().getListeEquipes().size());
                    // probleme a la fin de la boucle
                }
            }
			
			
        }
        this.horloge.setEndTime();
			if(this.horloge.getTempsAttente()>0)this.horloge.next();
        this.getModel().getView().repeindre();
        
        //System.out.println("La taille de la liste des equipes est : " +this.getModel().getArene().getListeEquipes().size());
        
        //System.out.println("Avant fonction horloge : ");
        

    }
    
    public Horloge getHorloge() {
        return horloge;
    }
    
    public Model getModel() {
        return model;
    }
 
    public void setArret(boolean arret) {
        this.arret = arret;
    }
}
